package com.koron.tool.frame;

import java.awt.Component;
import java.awt.Toolkit;
import java.awt.datatransfer.*;
import java.awt.event.*;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.tree.*;

import org.koron.ebs.util.field.FieldBean;

import com.koron.mybatis.SessionFactory;
import com.koron.tool.MainFrame;
import com.koron.tool.dialog.FieldFlagDialog;
import com.koron.tool.dialog.FieldTypeDialog;
import com.koron.ui.MutableGridLayout;
import com.koron.ui.POJOToFrame;
import com.koron.web.bean.DefineFieldBean;
import com.koron.web.bean.LayerBean;
import com.koron.web.mapper.UserDefineMapper;

/**
 * 用户自定义界面
 * 
 * @author swan
 *
 */
public class UserDefineFrame extends JInternalFrame {
	private static final Map<Long, String> typeMap = new HashMap<Long, String>();
	static {
		typeMap.put(FieldBean.COMBIN, "组合");
		typeMap.put(FieldBean.TEXTFIELD, "文本框");
		typeMap.put(FieldBean.SELECT, "下拉框");
		typeMap.put(FieldBean.RADIO, "单选框");
		typeMap.put(FieldBean.CHECKBOX, "复选框");
		typeMap.put(FieldBean.BUTTON, "按钮");
		typeMap.put(FieldBean.LABEL, "文本");
		typeMap.put(FieldBean.IMAGE, "图片");
		typeMap.put(FieldBean.TEXTAREA, "大文本");
	}
	private static UserDefineFrame instance;

	private DefaultTableModel dtm = new DefaultTableModel(new String[] { "ID", "名称", "标题", "描述", "类型", "类名", "序号" }, 0);

	private JTree tree = new JTree();

	private JSplitPane split;
	private JSplitPane splitRight;
	private Integer layerId;
	/**
	 * 字段
	 */
	private final JTable jtb = new JTable(dtm) {
		public boolean isCellEditable(int row, int column) {
			return false;
		}
	};

	// 以下为字段的属性
	private JPanel fieldPanel = new JPanel();
	private JTextField jtfName = new JTextField();
	private JTextField jtfCaption = new JTextField();
	private JTextField jtfClassName = new JTextField();
	private JTextField jtfDesc = new JTextField();
	private JTextField jtfLength = new JFormattedTextField(new DecimalFormat());
	private JTextField jtfSN = new JFormattedTextField(new DecimalFormat());
	private JTextArea jtaParam = new JTextArea();
	private JTextField jtfLayer = new JTextField();
	private JTextField jtfId = new JTextField();
	private JTextField jtfDefaultValue = new JTextField();
	public JTextField jtfType = new JTextField();
	public JTextField jtfFlag = new JTextField();
	public JTextField jtfRegx = new JTextField();
	public MainFrame frame;

	public static synchronized UserDefineFrame getInstance(MainFrame frame) {
		if (instance != null && !instance.isClosed)
			return instance;
		instance = new UserDefineFrame(frame);
		return instance;
	}

	private UserDefineFrame(MainFrame frame) {
		super("数据库设置");
		this.frame = frame;
		setSize(800, 600);
		setMaximizable(true);
		setClosable(true);
		setIconifiable(true);
		setResizable(true);
		JPanel panel = fieldPanel;
		MutableGridLayout layout = new MutableGridLayout(4, 10, 5, 5);
		layout.setHeight(0, 30);
		layout.setHeight(1, 30);
		layout.setHeight(2, 30);
		layout.setHeight(3, 30);
		layout.setHeight(4, 30);
		layout.setHeight(5, 30);
		layout.setHeight(6, 30);
		layout.setHeight(8, 30);
		layout.setWidth(0, 80);
		layout.setWidth(2, 80);
		layout.merge(1, 5, 3, 5);
		layout.merge(1, 6, 3, 6);
		layout.merge(1, 7, 3, 7);
		layout.merge(0, 8, 3, 8);

		panel.setLayout(layout);
		panel.add(new JLabel("ID"));
		panel.add(jtfId);
		jtfId.setName("id");
		panel.add(new JLabel("层别"));
		panel.add(jtfLayer);
		jtfLayer.setName("layerid");
		panel.add(new JLabel("名称"));
		panel.add(jtfName);
		jtfName.setName("name");
		panel.add(new JLabel("标题"));
		panel.add(jtfCaption);
		jtfCaption.setName("caption");
		panel.add(new JLabel("类型"));
		panel.add(jtfType);
		jtfType.setName("type");
		jtfType.setEditable(false);
		final UserDefineFrame self = this;
		jtfType.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				if (e.getClickCount() > 1) {
					FieldTypeDialog dialog = new FieldTypeDialog(self, Integer.parseInt(jtfType.getText()));
					dialog.setVisible(true);
					jtfType.setText(dialog.getValue() + "");
				}
			}
		});

		panel.add(new JLabel("描述"));
		panel.add(jtfDesc);
		jtfDesc.setName("desc");
		panel.add(new JLabel("类名"));
		panel.add(jtfClassName);
		jtfClassName.setName("className");
		panel.add(new JLabel("长度"));
		panel.add(jtfLength);
		jtfLength.setName("length");
		panel.add(new JLabel("顺序"));
		panel.add(jtfSN);
		jtfSN.setName("sn");
		panel.add(new JLabel("缺省值"));
		panel.add(jtfDefaultValue);
		jtfDefaultValue.setName("defaultValue");

		panel.add(new JLabel("标识"));
		panel.add(jtfFlag);
		jtfFlag.setName("flag");
		jtfFlag.setEditable(false);
		jtfFlag.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				if (e.getClickCount() > 1) {
					FieldFlagDialog dialog = new FieldFlagDialog(self, Integer.parseInt(jtfFlag.getText()));
					dialog.setVisible(true);
					jtfFlag.setText(dialog.getValue() + "");
				}
			}
		});
		panel.add(new JLabel("验证"));
		panel.add(jtfRegx);
		jtfRegx.setName("validate");
		jtfRegx.setToolTipText(
				"<html><pre>class='mail'　　//邮箱验证\n"+
				"class='url'　　//URL网址验证\n"+
				"class='date'　　//正确的日期 格式满足 2012，0204，2012-02-04\n"+
				"class='number'　　//输入合法的数字\n"+
				"class='digits'　　//输入整数\n"+
				"minlength=''　　//最小输入长度\n"+
				"maxlength=''　　//最长输入长度(该值不会提示，当值达到一定字符数不可再增长)\n"+
				"max=''　　//输入的数值小于指定值\n"+
				"min=''</pre></html>");
		panel.add(new JLabel("参数"));
		panel.add(new JScrollPane(jtaParam));
		jtaParam.setName("param");
		panel.add(new JButton(new SaveAction(this)));

		splitRight = new JSplitPane(JSplitPane.VERTICAL_SPLIT, new JScrollPane(jtb), panel);
		splitRight.setDividerSize(6);
		splitRight.setDividerLocation(200);
		splitRight.setResizeWeight(0.2);

		split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, new JScrollPane(tree), splitRight);
		split.setDividerSize(10);
		split.setDividerLocation(200);
		split.setResizeWeight(0.2);
		getContentPane().add(split);
		initTree();
		jtb.setRowHeight(30);
		jtb.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		jtb.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
			@Override
			public void valueChanged(ListSelectionEvent e) {
				if (jtb.getSelectedRow() != -1)
					loadBean((DefineFieldBean) jtb.getValueAt(jtb.getSelectedRow(), 0));
			}
		});
		jtb.getColumnModel().getColumn(0).setCellRenderer(new DefaultTableCellRenderer() {
			@Override
			public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
					boolean hasFocus, int row, int column) {
				try {
					DefineFieldBean bean = (DefineFieldBean)value;
					if (bean != null)
						return super.getTableCellRendererComponent(table, bean.getId(), isSelected, hasFocus, row, column);
				} catch (NumberFormatException e) {
				}
				return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
			}
		});
		jtb.getColumnModel().getColumn(4).setCellRenderer(new DefaultTableCellRenderer() {
			@Override
			public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
					boolean hasFocus, int row, int column) {
				try {
					Integer val = Integer.parseInt(String.valueOf(value));
					String str = getType(val);
					if (str != null)
						return super.getTableCellRendererComponent(table, str, isSelected, hasFocus, row, column);
				} catch (NumberFormatException e) {
				}
				return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
			}
		});
		setVisible(true);
	}

	private void initTree() {
		SessionFactory factory = new SessionFactory();
		UserDefineMapper mapper = factory.getMapper(UserDefineMapper.class);
		DefaultMutableTreeNode root = new DefaultMutableTreeNode("根节点");
		tree.setModel(new DefaultTreeModel(root));
		load(-1, root, mapper);
		factory.close();
		tree.setCellRenderer(new DefaultTreeCellRenderer() {
			@Override
			public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded,
					boolean leaf, int row, boolean hasFocus) {
				super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
				Object tmp = ((DefaultMutableTreeNode) value).getUserObject();
				if (tmp instanceof LayerBean) {
					LayerBean bean = ((LayerBean) tmp);
					String ret = bean.getName() + (bean.getNumber() == null ? "(0)" : "(" + bean.getNumber() + ")");
					ret += (bean.getLocked() == 1 ? "<font color=\"red\">已锁</font>" : "");
					this.setText("<html>" + ret + "</html>");
				}
				return this;
			}
		});
		tree.addTreeSelectionListener(new TreeSelectionListener() {
			@Override
			public void valueChanged(TreeSelectionEvent e) {
				TreePath tp = e.getNewLeadSelectionPath();
				if (tp == null)
					return;
				Object tmp = ((DefaultMutableTreeNode) tp.getLastPathComponent()).getUserObject();
				if (tmp instanceof LayerBean) {
					loadTable(((LayerBean) tmp).getId());
				}
			}
		});

		tree.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				if (e.getButton() == MouseEvent.BUTTON3) {
					TreePath tp = tree.getPathForLocation(e.getX(), e.getY());
					Object tmp = ((DefaultMutableTreeNode) tp.getLastPathComponent()).getUserObject();
					if (!(tmp instanceof LayerBean))
						return;
					JPopupMenu menu = new JPopupMenu();
					menu.add(new AddLevelAction(frame, (LayerBean) tmp, (DefaultMutableTreeNode) (tp
							.getLastPathComponent())));
					menu.add(new DeleteLayerAction(frame, tree, (LayerBean) tmp, (DefaultMutableTreeNode) (tp
							.getLastPathComponent())));
					menu.add(new LockAction(tree, (LayerBean) tmp, (DefaultMutableTreeNode) (tp.getLastPathComponent())));
					menu.add(new CopyAction(frame, tree, (LayerBean) tmp, (DefaultMutableTreeNode) (tp
							.getLastPathComponent())));
					menu.add(new ParseAction(frame, tree, (LayerBean) tmp, (DefaultMutableTreeNode) (tp
							.getLastPathComponent())));
					menu.show(tree, e.getX(), e.getY());
				}
				super.mouseClicked(e);
			}
		});
	}

	protected void loadTable() {
		loadTable(layerId);
	}

	protected void loadTable(int id) {
		SessionFactory factory = new SessionFactory();
		UserDefineMapper mapper = factory.getMapper(UserDefineMapper.class);
		List<DefineFieldBean> list = mapper.getFieldBeans(id);
		jtfLayer.setText("" + id);
		dtm.setRowCount(0);
		for (DefineFieldBean defineFieldBean : list) {
			Object[] arr = new Object[7];
			arr[0] = defineFieldBean;
			arr[1] = defineFieldBean.getName();
			arr[2] = defineFieldBean.getCaption();
			arr[3] = defineFieldBean.getDesc();
			arr[4] = defineFieldBean.getType() + "";
			arr[5] = defineFieldBean.getClassName();
			arr[6] = defineFieldBean.getSn() + "";
			dtm.addRow(arr);
		}
		factory.close();
		layerId = id;
	}

	private void load(int groupId, DefaultMutableTreeNode parent, UserDefineMapper mapper) {
		int num = parent.getChildCount();
		for (int i = 0; i < num; i++)
			((DefaultTreeModel) tree.getModel()).removeNodeFromParent((DefaultMutableTreeNode) parent.getLastChild());

		List<LayerBean> list = mapper.getLaysers(groupId);
		int i = 0;
		for (LayerBean layerBean : list) {
			DefaultMutableTreeNode node = new DefaultMutableTreeNode(layerBean);
			load(layerBean.getId(), node, mapper);
			((DefaultTreeModel) tree.getModel()).insertNodeInto(node, parent, i++);
		}
	}

	protected void loadBean(DefineFieldBean bean) {
		new POJOToFrame(fieldPanel).fromPOJO(bean);
	}

	class SaveAction extends AbstractAction {
		UserDefineFrame frame;

		public SaveAction(UserDefineFrame frame) {
			super();
			putValue(NAME, "保存");
			putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_MASK));
			this.frame = frame;
		}

		@Override
		public void actionPerformed(ActionEvent e) {
			setEnabled(false);
			DefineFieldBean bean = new POJOToFrame(fieldPanel).toPOJO(DefineFieldBean.class);
			SessionFactory factory = new SessionFactory();
			int ret = 0;
			if (bean.getId().trim().equals("-1"))
				ret = factory.getMapper(UserDefineMapper.class).addFieldBean(bean);
			else {
				DefineFieldBean fb = factory.getMapper(UserDefineMapper.class).getFieldBeanById(
						Integer.parseInt(jtfId.getText()));
				if (!fb.getLayerid().equals(bean.getLayerid())) {
					if (JOptionPane.showConfirmDialog(frame, "层别发生改动，是否把此字段移到新的位置", "是否要移到新层别",
							JOptionPane.YES_NO_OPTION) == JOptionPane.NO_OPTION)
					{
						factory.close();
						setEnabled(true);
						return;
					}
				}
				ret = factory.getMapper(UserDefineMapper.class).updateFieldBean(bean);
			}
			factory.close();
			if (ret == 0)
				JOptionPane.showMessageDialog(frame, "数据更新失败，有可能是层已经被锁定");
			else
				JOptionPane.showMessageDialog(frame, "变更" + ret + "条数据");
			setEnabled(true);
			frame.loadTable();
			
		}
	}

	private String getType(int value) {
		int val = (value & 0xFFFF0000);
		return typeMap.get((long) val);
	}

	class AddLevelAction extends AbstractAction {
		MainFrame frame;
		LayerBean bean;
		DefaultMutableTreeNode node;

		public AddLevelAction(MainFrame frame, LayerBean bean, DefaultMutableTreeNode node) {
			this.frame = frame;
			this.bean = bean;
			this.node = node;
			putValue(NAME, "添加节点");
		}

		@Override
		public void actionPerformed(ActionEvent e) {
			String str = JOptionPane.showInputDialog(frame, "请输入节点名称");
			if (str != null && !str.isEmpty()) {
				SessionFactory factory = new SessionFactory();
				LayerBean bean = new LayerBean();
				bean.setInherit(false);
				bean.setName(str);
				bean.setParentid(this.bean.getId());
				UserDefineMapper mapper = factory.getMapper(UserDefineMapper.class);
				mapper.addLayer(bean);
				load(bean.getParentid(), node, mapper);
				factory.close();
			}
		}
	}

	class LockAction extends AbstractAction {
		LayerBean bean;
		DefaultMutableTreeNode node;
		JTree tree;

		LockAction(JTree tree, LayerBean bean, DefaultMutableTreeNode node) {
			this.bean = bean;
			this.node = node;
			this.tree = tree;
			putValue(NAME, "锁定(解锁)");
		}

		@Override
		public void actionPerformed(ActionEvent e) {
			SessionFactory factory = new SessionFactory();
			UserDefineMapper mapper = factory.getMapper(UserDefineMapper.class);
			mapper.lockLayer(bean.getId());
			node.setUserObject(mapper.getLayerBean(bean.getId()));
			factory.close();
			tree.updateUI();
		}
	}

	class DeleteLayerAction extends AbstractAction {
		LayerBean bean;
		DefaultMutableTreeNode node;
		JTree tree;
		MainFrame frame;

		DeleteLayerAction(MainFrame frame, JTree tree, LayerBean bean, DefaultMutableTreeNode node) {
			this.bean = bean;
			this.node = node;
			this.tree = tree;
			this.frame = frame;
			putValue(NAME, "删除节点");
		}

		@Override
		public void actionPerformed(ActionEvent e) {
			if (node.getChildCount() > 0) {
				JOptionPane.showMessageDialog(frame, "存在子节点，不能删除");
				return;
			}
			SessionFactory factory = new SessionFactory();
			UserDefineMapper mapper = factory.getMapper(UserDefineMapper.class);
			List<DefineFieldBean> list = mapper.getFieldBeans(bean.getId());
			if (list.size() > 0) {
				JOptionPane.showMessageDialog(frame, "节点下有字段，不可删除，可以把些字段移到垃圾桶中去。");
				factory.close();
				return;
			}
			if (JOptionPane.showConfirmDialog(frame, "是否确定要删除该节点", "删除节点", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
				mapper.removeLayer(bean.getId());
				((DefaultTreeModel) tree.getModel()).removeNodeFromParent(node);
			}
			factory.close();
		}
	}

	/**
	 * 复制
	 * 
	 * @author swan
	 *
	 */
	class CopyAction extends AbstractAction {
		LayerBean bean;
		DefaultMutableTreeNode node;
		JTree tree;
		MainFrame frame;

		CopyAction(MainFrame frame, JTree tree, LayerBean bean, DefaultMutableTreeNode node) {
			this.bean = bean;
			this.node = node;
			this.tree = tree;
			this.frame = frame;
			putValue(NAME, "复制字段");
		}

		@Override
		public void actionPerformed(ActionEvent e) {
			Clipboard b = Toolkit.getDefaultToolkit().getSystemClipboard();
			StringSelection selection = new StringSelection(String.valueOf(bean.getId()));
			b.setContents(selection, null);

		}
	}

	/**
	 * 粘贴
	 * 
	 * @author swan
	 *
	 */
	class ParseAction extends AbstractAction {
		LayerBean bean;
		DefaultMutableTreeNode node;
		JTree tree;
		MainFrame frame;

		ParseAction(MainFrame frame, JTree tree, LayerBean bean, DefaultMutableTreeNode node) {
			this.bean = bean;
			this.node = node;
			this.tree = tree;
			this.frame = frame;
			putValue(NAME, "粘贴字段");
		}

		@Override
		public void actionPerformed(ActionEvent e) {
			if (bean.getLocked() == 1) {
				JOptionPane.showMessageDialog(frame, "节点已锁定，不能粘贴，请先解锁");
				return;
			}
			Clipboard b = Toolkit.getDefaultToolkit().getSystemClipboard();
			try {
				Object o = b.getData(DataFlavor.stringFlavor);
				if (o != null && o instanceof String) {
					if (JOptionPane.showConfirmDialog(frame, "是否要把复制的字段粘贴到此节点下", "是否粘贴", JOptionPane.YES_NO_OPTION) == JOptionPane.NO_OPTION)
						return;
					SessionFactory factory = new SessionFactory();
					UserDefineMapper mapper = factory.getMapper(UserDefineMapper.class);
					List<DefineFieldBean> list = mapper.getFieldBeans(Integer.parseInt(o.toString()));
					for (DefineFieldBean defineFieldBean : list) {
						defineFieldBean.setLayerid(bean.getId());
						mapper.addFieldBean(defineFieldBean);
					}
					load(bean.getId(), node, mapper);
					factory.close();
				}
			} catch (UnsupportedFlavorException e1) {
				e1.printStackTrace();
			} catch (IOException e1) {
				e1.printStackTrace();
			}

		}
	}
}
